package com.zx._03_并发.chapter_08_threadLocal;

import com.zx.common.entity.User2;
import java.util.Date;
import java.util.stream.IntStream;
import lombok.extern.slf4j.Slf4j;


/**
 * @version v1.0
 * @Project: knowledge
 * @Title: ThreadLocalDemo2
 * @Description: 父子线程通讯
 *         https://www.cnblogs.com/Nonnetta/p/10175662.html
 * @author: zhangxue
 * @date: 2020年4月29日下午1:22:21
 * @company: 未知
 * @Copyright: Copyright (c) 2015
 */
@Slf4j
public class 父子线程通讯 {

    public static void main(final String[] args) throws Exception {
        //test1();
        //test2();
        test3();
    }

    public static void test1() {
        final ThreadLocal<String> local = new ThreadLocal<String>();
        local.set("当前线程");
        IntStream
                .range(0, 10)// 获得0~9  10个值
                .parallel()// 多线程并发处理，线程数取决于cpu核心数， jdk计算公式=cup * 2
                .forEach(i -> log.info("i={}, local={}", i, local.get()));
		/*
		打印结果:只有当前线程main能获得local的值，main线程的子线程无法获得
		2020-04-29 12:57:14.803 [ForkJoinPool.commonPool-worker-5] INFO  c.z._.c.ThreadLocalDemo2 - i=2, local=null
		2020-04-29 12:57:14.803 [ForkJoinPool.commonPool-worker-7] INFO  c.z._.c.ThreadLocalDemo2 - i=5, local=null
		2020-04-29 12:57:14.802 [main] INFO  c.z._.c.ThreadLocalDemo2 - i=6, local=当前线程
		2020-04-29 12:57:14.803 [ForkJoinPool.commonPool-worker-3] INFO  c.z._.c.ThreadLocalDemo2 - i=8, local=null
		2020-04-29 12:57:14.815 [ForkJoinPool.commonPool-worker-7] INFO  c.z._.c.ThreadLocalDemo2 - i=7, local=null
		2020-04-29 12:57:14.817 [ForkJoinPool.commonPool-worker-5] INFO  c.z._.c.ThreadLocalDemo2 - i=4, local=null
		2020-04-29 12:57:14.817 [ForkJoinPool.commonPool-worker-3] INFO  c.z._.c.ThreadLocalDemo2 - i=9, local=null
		2020-04-29 12:57:14.817 [ForkJoinPool.commonPool-worker-3] INFO  c.z._.c.ThreadLocalDemo2 - i=0, local=null
		2020-04-29 12:57:14.817 [ForkJoinPool.commonPool-worker-7] INFO  c.z._.c.ThreadLocalDemo2 - i=1, local=null
		2020-04-29 12:57:14.817 [ForkJoinPool.commonPool-worker-5] INFO  c.z._.c.ThreadLocalDemo2 - i=3, local=null
		*/
    }

    public static void test2() {
        final InheritableThreadLocal<String> local2 = new InheritableThreadLocal<String>();
        // 使用inheritableThreadLocal ，是在新线程生成的时候，就将父线程的ThreadLocalMap传递给子线程，
        // 因为实际中，线程都是复用的，所有这个实现的方式没有解决父子线程之间的通讯问题
        local2.set("inheritable");
        IntStream
                .range(0, 10)// 获得0~9  10个值
                .parallel()// 多线程并发处理，线程数取决于cpu核心数， jdk计算公式=cup * 2
                .forEach(i -> log.info("i={}, local={}", i, local2.get()));
		/*
	 	2020-04-29 13:20:01.860 [ForkJoinPool.commonPool-worker-7] INFO  c.z._.c.ThreadLocalDemo2 - i=5, local=inheritable
		2020-04-29 13:20:01.859 [ForkJoinPool.commonPool-worker-5] INFO  c.z._.c.ThreadLocalDemo2 - i=8, local=inheritable
		2020-04-29 13:20:01.860 [main] INFO  c.z._.c.ThreadLocalDemo2 - i=6, local=inheritable
		2020-04-29 13:20:01.878 [ForkJoinPool.commonPool-worker-7] INFO  c.z._.c.ThreadLocalDemo2 - i=1, local=inheritable
		2020-04-29 13:20:01.859 [ForkJoinPool.commonPool-worker-3] INFO  c.z._.c.ThreadLocalDemo2 - i=2, local=inheritable
		2020-04-29 13:20:01.879 [ForkJoinPool.commonPool-worker-5] INFO  c.z._.c.ThreadLocalDemo2 - i=9, local=inheritable
		2020-04-29 13:20:01.879 [ForkJoinPool.commonPool-worker-7] INFO  c.z._.c.ThreadLocalDemo2 - i=0, local=inheritable
		2020-04-29 13:20:01.879 [ForkJoinPool.commonPool-worker-5] INFO  c.z._.c.ThreadLocalDemo2 - i=7, local=inheritable
		2020-04-29 13:20:01.879 [ForkJoinPool.commonPool-worker-7] INFO  c.z._.c.ThreadLocalDemo2 - i=3, local=inheritable
		2020-04-29 13:20:01.879 [ForkJoinPool.commonPool-worker-3] INFO  c.z._.c.ThreadLocalDemo2 - i=4, local=inheritable
		 */
        local2.set("2222222222");//修改这个值，这就不行了
        IntStream
                .range(0, 10)// 获得0~9  10个值
                .parallel()// 多线程并发处理，线程数取决于cpu核心数， jdk计算公式=cup * 2
                .forEach(i -> log.info("i={}, local={}", i, local2.get()));
    }

    public static void test3() {
        final User2 user = new User2(1, "tom", new Date());
        final InheritableThreadLocal<User2> local = new InheritableThreadLocal<User2>();
        local.set(user);

        IntStream
                .range(0, 10)
                .parallel()
                .forEach(i -> log.info("i={}, local={}", i, local.get()));

        System.out.println();
        System.out.println();

        // 修改共享的对象
        // user.setId(99); // 对象是共享的，所有修改后父子线程都能看到
        final User2 user2 = new User2(2, "AAA", new Date());// 将父线程的对象替换成别的就不行了
        local.set(user2);

        IntStream
                .range(0, 10)
                .parallel()
                .forEach(i -> log.info("i={}, local={}", i, local.get()));
		/*
		2020-04-29 13:35:13.375 [main] INFO  c.z._.chapter_09_threadLocal.父子线程通讯 - i=6, local=User [id=2, name=AAA, birtday=Wed Apr 29 13:35:13 CST 2020]
		2020-04-29 13:35:13.377 [main] INFO  c.z._.chapter_09_threadLocal.父子线程通讯 - i=5, local=User [id=2, name=AAA, birtday=Wed Apr 29 13:35:13 CST 2020]
		2020-04-29 13:35:13.378 [main] INFO  c.z._.chapter_09_threadLocal.父子线程通讯 - i=8, local=User [id=2, name=AAA, birtday=Wed Apr 29 13:35:13 CST 2020]
		2020-04-29 13:35:13.376 [ForkJoinPool.commonPool-worker-3] INFO  c.z._.chapter_09_threadLocal.父子线程通讯 - i=2, local=User [id=1, name=tom, birtday=Wed Apr 29 13:35:13 CST 2020]
		2020-04-29 13:35:13.378 [ForkJoinPool.commonPool-worker-5] INFO  c.z._.chapter_09_threadLocal.父子线程通讯 - i=7, local=User [id=1, name=tom, birtday=Wed Apr 29 13:35:13 CST 2020]
		2020-04-29 13:35:13.379 [ForkJoinPool.commonPool-worker-3] INFO  c.z._.chapter_09_threadLocal.父子线程通讯 - i=4, local=User [id=1, name=tom, birtday=Wed Apr 29 13:35:13 CST 2020]
		2020-04-29 13:35:13.381 [ForkJoinPool.commonPool-worker-3] INFO  c.z._.chapter_09_threadLocal.父子线程通讯 - i=3, local=User [id=1, name=tom, birtday=Wed Apr 29 13:35:13 CST 2020]
		2020-04-29 13:35:13.378 [ForkJoinPool.commonPool-worker-7] INFO  c.z._.chapter_09_threadLocal.父子线程通讯 - i=9, local=User [id=1, name=tom, birtday=Wed Apr 29 13:35:13 CST 2020]
		2020-04-29 13:35:13.380 [ForkJoinPool.commonPool-worker-5] INFO  c.z._.chapter_09_threadLocal.父子线程通讯 - i=1, local=User [id=1, name=tom, birtday=Wed Apr 29 13:35:13 CST 2020]
		2020-04-29 13:35:13.382 [ForkJoinPool.commonPool-worker-3] INFO  c.z._.chapter_09_threadLocal.父子线程通讯 - i=0, local=User [id=1, name=tom, birtday=Wed Apr 29 13:35:13 CST 2020]
		*/
    }


}
